package net.asrsmid.sample.adventureanalyzer;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.google.gson.Gson;

import net.asrsmid.connection.AsRsApplicationPool;
import net.asrsmid.connection.AsRsApplicationPoolManager;
import net.asrsmid.invoker.as.Table;
import net.asrsmid.invoker.as.TableException;
import net.asrsmid.invoker.as.TableUtility;
import net.asrsmid.sample.adventureanalyzer.model.AnalysisContext;
import net.asrsmid.sample.adventureanalyzer.model.AnalysisResult;
import net.asrsmid.sample.adventureanalyzer.service.AdventureAnalyzerAsService;
import net.asrsmid.sample.adventureanalyzer.service.AdventureAnalyzerRsService;

/**
 * Servlet implementation class AdventureAnalyzer
 */
public class AdventureAnalyzerServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private AsRsApplicationPool appPool;

	public void init() throws ServletException {
		super.init();
		String configFilePath = getServletContext().getRealPath("WEB-INF/asrsmidsample-conf.xml");
		appPool = AsRsApplicationPoolManager.getApplicationPool(configFilePath);
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		handleRequest(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		handleRequest(request, response);
	}
	
	private boolean login(HttpServletRequest request, HttpServletResponse response) {
		return true;
	}

	private void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String serviceType = request.getParameter("serviceType");
		String requestType = request.getParameter("requestType");
	
		if ("login".equalsIgnoreCase(serviceType)) {
			boolean login = login(request, response);
			
			PrintWriter pw = response.getWriter();
			pw.write(Boolean.toString(login));
			pw.flush();
			pw.close();
		} else if ("as".equalsIgnoreCase(serviceType)) {
			AdventureAnalyzerAsService svc = new AdventureAnalyzerAsService(appPool);

			if ("GET_AXISELMS".equalsIgnoreCase(requestType)) {
				String result = svc.getAxisMembers(request.getParameter("axis"));
				StringBuilder sb = new StringBuilder("{rows:");
				sb.append(result).append("}");
				
				PrintWriter pw = response.getWriter();
				pw.write(sb.toString());
				pw.flush();
				pw.close();
			} else if ("GET_REPORT".equalsIgnoreCase(requestType)) {
				AnalysisContext ctx = parseToAnalysisContext(request.getParameter("context"));
				Table table = svc.getReport(ctx);
				byte[] result = null;
				
				if ("extjs".equals(ctx.getReportFormat())) {
					String jsStr = TableUtility.toJsArrayString(table);
					result = jsStr.getBytes();
				} else if ("xls".equals(ctx.getReportFormat())) {
					try {
						result = TableUtility.toExcel(table);
					} catch (TableException e) {
						e.printStackTrace();
					}
					response.setContentType("application/vnd.ms-excel");
		            response.addHeader("Content-Disposition", "attachment;filename=\"AdventureAnalyzer.xls\"");
				} else if ("csv".equals(ctx.getReportFormat())) {
					try {
						result = TableUtility.toCsv(table);
					} catch (TableException e) {
						e.printStackTrace();
					}
					response.setContentType("application/octet-stream");
		            response.addHeader("Content-Disposition", "attachment;filename=\"AdventureAnalyzer.csv\"");
				} else if ("xml".equals(ctx.getReportFormat())) {
					result = TableUtility.toXml(table);
					response.setContentType("application/octet-stream");
		            response.addHeader("Content-Disposition", "attachment;filename=\"AdventureAnalyzer.xml\"");
				}
				
				OutputStream os = response.getOutputStream();
				os.write(result);
				os.flush();
				os.close();
			}
		} else if ("rs".equalsIgnoreCase(serviceType)) {
			AdventureAnalyzerRsService svc = new AdventureAnalyzerRsService(appPool);

			if ("GET_AXISELMS".equalsIgnoreCase(requestType)) {
				String result = svc.getAxisMembers(request.getParameter("axis"));
				StringBuilder sb = new StringBuilder("{rows:");
				sb.append(result).append("}");
				
				PrintWriter pw = response.getWriter();
				pw.write(sb.toString());
				pw.flush();
				pw.close();
			} else if ("GET_REPORT".equalsIgnoreCase(requestType)) {
				AnalysisContext ctx = parseToAnalysisContext(request.getParameter("context"));
				Object result = svc.getReport(ctx);
				
				OutputStream os = response.getOutputStream();
				os.write(((AnalysisResult) result).getData());
				os.flush();
				os.close();
			}
		}
	}

	private AnalysisContext parseToAnalysisContext(String jsonCtxString) {
		Gson gson = new Gson();
		AnalysisContext ctx = gson.fromJson(jsonCtxString, AnalysisContext.class);
		return ctx;
	}
}